home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / uupc11yt.zip / UTIL / UUPOLL.C < prev   
C/C++ Source or Header  |  1993-04-14  |  34KB  |  931 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    Program:    uupoll.c              22 September 1989             */
  3. /*    Author:     Andrew H. Derbyshire                                */
  4. /*                108 Decatur St                                      */
  5. /*                Arlington, MA 02174                                 */
  6. /*    Internet:   help@kew.com                                        */
  7. /*    Function:   Performs autopoll functions for UUCICO              */
  8. /*    Language:   Borland C++ 2.0                                     */
  9. /*    Usage:      uupoll [-r 0] [-f hhmm] [-i hhmm|0400 ]             */
  10. /*                       [-d hhmm] [-e hhmm]                          */
  11. /*                       [-a hhmm] [-x debug] [-s systems]            */
  12. /*                                                                    */
  13. /*                Where:                                              */
  14. /*                                                                    */
  15. /*                -r 0     specifies that UUCICO is to run            */
  16. /*                         into passive mode when waiting to          */
  17. /*                         poll out                                   */
  18. /*                                                                    */
  19. /*                -r 1     specifies that UUCICO will not run         */
  20. /*                         in passive mode while waiting to           */
  21. /*                         poll out, but polling out will             */
  22. /*                         occur.                                     */
  23. /*                                                                    */
  24. /*                -f hhmm  is the first time in the day that          */
  25. /*                         UUCICO is to poll out.  If omitted,        */
  26. /*                         polling begins after the interval          */
  27. /*                         specified with -i.                         */
  28. /*                                                                    */
  29. /*                -i hhmm  the interval the UUCICO is to poll         */
  30. /*                         out at.  If omitted, a period of 4         */
  31. /*                         hours will be used.                        */
  32. /*                                                                    */
  33. /*                -d hhmm  Terminate polling after hhmm.              */
  34. /*                         Default is not to terminate.               */
  35. /*                                                                    */
  36. /*                -e hhmm  Terminate polling at hhmm                  */
  37. /*                         Default is not to terminate.               */
  38. /*                                                                    */
  39. /*                -a hhmm  Automatically poll actively using the      */
  40. /*                         system name "any" after any                */
  41. /*                         successful inbound poll if hhmm have       */
  42. /*                         past since last poll.  hhmm may be         */
  43. /*                         0000.                                      */
  44. /*                                                                    */
  45. /*                In addition, the following flags will be passed     */
  46. /*                to UUCICO:                                          */
  47. /*                                                                    */
  48. /*                -s system      system name to poll.  By default,    */
  49. /*                               UUCICO will be invoked with          */
  50. /*                               '-s all' followed by '-s any'.       */
  51. /*                                                                    */
  52. /*                -x n           debug level.   The default level     */
  53. /*                               is 1.                                */
  54. /*--------------------------------------------------------------------*/
  55.  
  56. /*--------------------------------------------------------------------*/
  57. /*                          RCS Information                           */
  58. /*--------------------------------------------------------------------*/
  59.  
  60. /*
  61.  *    $Id: UUPOLL.C 1.7 1993/04/14 10:29:53 ahd Exp $
  62.  *
  63.  *    $Log: UUPOLL.C $
  64.  * Revision 1.7  1993/04/14  10:29:53  ahd
  65.  * Correct invalid exit time if both -e and -f flags specified
  66.  *
  67.  * Revision 1.6  1993/04/10  21:25:16  dmwatt
  68.  * Add Windows/NT support
  69.  *
  70.  * Revision 1.6  1993/04/10  21:25:16  dmwatt
  71.  * Add Windows/NT support
  72.  *
  73.  * Revision 1.5  1993/04/04  04:57:01  ahd
  74.  * Return exit code of UUCICO upon exit
  75.  *
  76.  * Revision 1.4  1993/03/06  23:04:54  ahd
  77.  * Add cr after auto-clean message
  78.  *
  79.  * Revision 1.3  1992/11/20  12:41:01  ahd
  80.  * Fix TZ change bug
  81.  *
  82.  * Revision 1.2  1992/11/15  04:45:46  ahd
  83.  * Correct polling for days time zone changes
  84.  *
  85.  * Revision 1.1  1992/11/15  04:29:22  ahd
  86.  * Initial revision
  87.  *
  88.  * Revision 1.1  1992/04/27  00:30:13  ahd
  89.  * Initial revision
  90.  *
  91.  */
  92.  
  93. static const char rcsid[] =
  94.          "$Id: UUPOLL.C 1.7 1993/04/14 10:29:53 ahd Exp $";
  95.  
  96. /*--------------------------------------------------------------------*/
  97. /*                        System include file                         */
  98. /*--------------------------------------------------------------------*/
  99.  
  100. #include <ctype.h>
  101. #include <dos.h>
  102. #include <limits.h>
  103. #include <process.h>
  104. #include <stdio.h>
  105. #include <stdlib.h>
  106. #include <string.h>
  107. #include <time.h>
  108. #include <conio.h>
  109. #include <direct.h>
  110. #include <signal.h>           /* Ctrl-Break handler               */
  111.  
  112. #ifdef __TURBOC__
  113. #include <alloc.h>
  114. unsigned _stklen = 2048;            /* Reduce memory usage           */
  115. unsigned _heaplen = 2048;           /* Reduce memory usage           */
  116. #else /* __TURBOC__ */
  117. #ifndef FAMILYAPI
  118. static int setcbrk(char state);
  119. #ifdef WIN32     /* In this module, WIN32 is a synonym for FAMILYAPI -- dmw 4/5/93 */
  120. #define FAMILYAPI
  121. #endif /* WIN32 */
  122. #endif /* FAMILYAPI */
  123. #endif /* __TURBOC__ */
  124.  
  125. /*--------------------------------------------------------------------*/
  126. /*                    UUPC/extended include files                     */
  127. /*--------------------------------------------------------------------*/
  128.  
  129. #include "getopt.h"
  130. #include "lib.h"
  131. #include "timestmp.h"
  132. #include "ssleep.h"
  133. #include "arpadate.h"
  134. #include "safeio.h"
  135. #include "dater.h"
  136.  
  137. /*--------------------------------------------------------------------*/
  138. /*                        Typedefs and macros                         */
  139. /*--------------------------------------------------------------------*/
  140.  
  141. typedef int hhmm;
  142.  
  143. /*--------------------------------------------------------------------*/
  144. /*                  Prototypes and global variables                   */
  145. /*--------------------------------------------------------------------*/
  146.  
  147. void   Catcher( void );
  148.  static active(char *Rmtname, int debuglevel, const char *logname);
  149. static void    busywork( time_t next);
  150. static int     execute( char *command );
  151. static time_t  nextpoll( hhmm first, hhmm interval );
  152. static boolean     notanumber( char *number);
  153. static void    usage( char *name );
  154.  
  155.  static int passive( time_t next,
  156.                      int debuglevel,
  157.                      const char *logname,
  158.                      const char *modem );
  159.  
  160. static hhmm    firstpoll(hhmm interval);
  161. static void    uuxqt( int debuglevel);
  162. static time_t LifeSpan( time_t duration, time_t stoptime );
  163.  
  164. static time_t now;            /* Current time, updated at start of
  165.                                  program and by busywork() and
  166.                                  execute()                           */
  167.  
  168. currentfile();
  169.  
  170. /*--------------------------------------------------------------------*/
  171. /*    m a i n                                                         */
  172. /*                                                                    */
  173. /*    main program                                                    */
  174. /*--------------------------------------------------------------------*/
  175.  
  176.  void main( int argc , char *argv[] )
  177.  {
  178.  
  179.    int option;
  180.    hhmm first = - 1;
  181.    hhmm interval = -1;
  182.    hhmm stoptime = -1;
  183.    hhmm duration = -1;
  184.    hhmm autowait = -1;
  185.    hhmm cleanup  = -1;
  186.    time_t cleannext = LONG_MAX;
  187.  
  188.    time_t exittime;
  189.    int nopassive = 2;
  190.    boolean done = FALSE;
  191.    char *Rmtname = NULL;
  192.    char *CleanCommand = "uuclean";
  193.    char *logname = NULL;
  194.    char *modem   = NULL;
  195.    int returncode = 0;
  196.  
  197. #ifndef FAMILYAPI
  198.    boolean cbrk;
  199. #endif
  200.  
  201.    banner(argv);
  202.  
  203.    if (!configure( B_UUPOLL ))
  204.       panic();
  205.  
  206.    tzset();
  207.    time( &now );
  208.  
  209.  
  210.     if( signal( SIGINT, Catcher ) == SIG_ERR )
  211.     {
  212.         fprintf( stderr, "uupoll: Couldn't set SIGINT\n" );
  213.         panic();
  214.     }
  215.  
  216.    while((option = getopt(argc, argv, "m:a:c:C:d:e:f:l:i:s:r:x:")) != EOF)
  217.    switch(option)
  218.    {
  219.  
  220. /*--------------------------------------------------------------------*/
  221. /*       Automatically poll "any" after an incoming phone call        */
  222. /*--------------------------------------------------------------------*/
  223.  
  224.       case 'a':
  225.          if (notanumber(optarg))
  226.             usage( argv[0] );
  227.          autowait = (hhmm) hhmm2sec( atoi(optarg) );
  228.          break;
  229.  
  230. /*--------------------------------------------------------------------*/
  231. /*                         First time to poll                         */
  232. /*--------------------------------------------------------------------*/
  233.  
  234.       case 'f':
  235.          if (notanumber(optarg))
  236.             usage( argv[0] );
  237.          first = atoi(optarg);
  238.          if ( interval == -1 )
  239.             interval = 400;
  240.          break;
  241.  
  242. /*--------------------------------------------------------------------*/
  243. /*                         First time to clean                        */
  244. /*--------------------------------------------------------------------*/
  245.  
  246.       case 'c':
  247.          if (notanumber(optarg))
  248.             usage( argv[0] );
  249.          cleanup = atoi(optarg);
  250.          break;
  251.  
  252. /*--------------------------------------------------------------------*/
  253. /*                    Clean-up command to execute                     */
  254. /*--------------------------------------------------------------------*/
  255.  
  256.       case 'C':
  257.          CleanCommand = optarg;
  258.          break;
  259.  
  260. /*--------------------------------------------------------------------*/
  261. /*                          UUCICO log file                           */
  262. /*--------------------------------------------------------------------*/
  263.  
  264.       case 'l':
  265.          logname = optarg;
  266.          break;
  267.  
  268.  
  269. /*--------------------------------------------------------------------*/
  270. /*                            Input modem                             */
  271. /*--------------------------------------------------------------------*/
  272.  
  273.       case 'm':
  274.          modem = optarg;
  275.          break;
  276.  
  277. /*--------------------------------------------------------------------*/
  278. /*                          Interval to poll                          */
  279. /*--------------------------------------------------------------------*/
  280.  
  281.       case 'i':
  282.          if (notanumber(optarg))
  283.             usage( argv[0] );
  284.          interval = atoi(optarg);
  285.          nopassive = min(1,nopassive);
  286.          break;
  287.  
  288. /*--------------------------------------------------------------------*/
  289. /*                      Duration to poll                              */
  290. /*--------------------------------------------------------------------*/
  291.  
  292.       case 'e':
  293.          if (notanumber(optarg))
  294.             usage( argv[0] );
  295.          stoptime = atoi(optarg);
  296.          break;
  297.  
  298. /*--------------------------------------------------------------------*/
  299. /*                      Time to exit                                  */
  300. /*--------------------------------------------------------------------*/
  301.  
  302.       case 'd':
  303.          if (notanumber(optarg))
  304.             usage( argv[0] );
  305.          duration = atoi(optarg);
  306.          break;
  307.  
  308.  
  309. /*--------------------------------------------------------------------*/
  310. /*                        System name to poll                         */
  311. /*--------------------------------------------------------------------*/
  312.  
  313.       case 's':
  314.          Rmtname = strdup(optarg);
  315.          break;
  316.  
  317. /*--------------------------------------------------------------------*/
  318. /*                            Debug level                             */
  319. /*--------------------------------------------------------------------*/
  320.  
  321.       case 'x':
  322.          if (notanumber(optarg))
  323.             usage( argv[0] );
  324.          debuglevel = atoi(optarg);
  325.          break;
  326.  
  327. /*--------------------------------------------------------------------*/
  328. /*                       Passive polling option                       */
  329. /*--------------------------------------------------------------------*/
  330.  
  331.       case 'r':
  332.          if (notanumber(optarg))
  333.             usage( argv[0] );
  334.          nopassive = atoi(optarg);
  335.          break;
  336.  
  337. /*--------------------------------------------------------------------*/
  338. /*                                Help                                */
  339. /*--------------------------------------------------------------------*/
  340.  
  341.       default:
  342.       case '?':
  343.          usage( argv[0] );
  344.    } /* switch */
  345.  
  346. /*--------------------------------------------------------------------*/
  347. /*             Terminate with error if too many arguments             */
  348. /*--------------------------------------------------------------------*/
  349.  
  350.    if (optind != argc)
  351.    {
  352.       puts("Extra parameters on command line.");
  353.       usage( argv[0] );
  354.    }
  355.  
  356. /*--------------------------------------------------------------------*/
  357. /* Terminate if neither active polling nor passive polling requested  */
  358. /*--------------------------------------------------------------------*/
  359.  
  360.    if ( nopassive == 2 && (first < 0))
  361.    {
  362.       puts("Must specify -r 0, -f hhmm, or -i hhmm");
  363.       usage( argv[0] );
  364.    }
  365.  
  366. /*--------------------------------------------------------------------*/
  367. /*                        Compute time to exit                        */
  368. /*--------------------------------------------------------------------*/
  369.  
  370.    exittime = LifeSpan( duration, stoptime );
  371.  
  372. /*--------------------------------------------------------------------*/
  373. /*                   Comput first time to poll out                    */
  374. /*--------------------------------------------------------------------*/
  375.  
  376.    if ( (interval > 0) && (first < 0))
  377.       first = firstpoll(interval);
  378.  
  379. /*--------------------------------------------------------------------*/
  380. /*            If running under MS-DOS, enable Cntrl-Break.            */
  381. /*--------------------------------------------------------------------*/
  382.  
  383. #ifndef FAMILYAPI
  384. #ifdef __TURBOC__
  385.  
  386.    cbrk = getcbrk();                /* Get original Cntrl-Break setting */
  387.  
  388.    if (!cbrk)
  389.       setcbrk(1);                   /* Turn it on to allow abort        */
  390.  
  391. #else /*dmw*/
  392.  
  393.    cbrk = setcbrk(1);      /* Turn it on to allow abort; get previous state */
  394.    printf("BREAK ON has been set\n");
  395.  
  396. #endif
  397. #endif
  398.  
  399. /*--------------------------------------------------------------------*/
  400. /*          Determine first time to perform clean-up, if any          */
  401. /*--------------------------------------------------------------------*/
  402.  
  403.       if (cleanup >= 0)
  404.       {
  405.          cleannext = nextpoll(cleanup, 2400);
  406.          printf("Automatic cleanup via \"%s\" scheduled for %s",
  407.                   CleanCommand, ctime(&cleannext));
  408.       }
  409.  
  410. /*--------------------------------------------------------------------*/
  411. /*                       Beginning of main loop                       */
  412. /*--------------------------------------------------------------------*/
  413.  
  414.    while ( !done && (exittime > now))
  415.    {
  416.       time_t next = LONG_MAX;
  417.       time_t autonext  = now + autowait;
  418.       time_t wait = 10;      /* Time to wait after first panic()    */
  419.       returncode = 0;
  420.  
  421. /*--------------------------------------------------------------------*/
  422. /*        Determine length of passive poll or wasting of time         */
  423. /*--------------------------------------------------------------------*/
  424.  
  425.       if (first >= 0)
  426.       {
  427.          next = nextpoll(first,interval);
  428.          if ( next > exittime )
  429.             next = exittime;
  430.       }
  431.       else
  432.          next = exittime;
  433.  
  434. /*--------------------------------------------------------------------*/
  435. /*              Disable OS/2 undelete support if desired              */
  436. /*--------------------------------------------------------------------*/
  437.  
  438.    if ( !bflag[ F_UNDELETE ] )
  439.       putenv( "DELDIR=");
  440.  
  441. /*--------------------------------------------------------------------*/
  442. /*    Begin passive polling (with optional active calls system        */
  443. /*    "any") until next active poll or exit time is reached.          */
  444. /*--------------------------------------------------------------------*/
  445.  
  446.       while ((now < next) && ! done )
  447.       {
  448.  
  449.          if ( cleannext < now )
  450.          {
  451.             printf("Performing auto-clean with command: %s\n",
  452.                      CleanCommand );
  453.             if (system( CleanCommand ))
  454.                printerr( CleanCommand );
  455.             cleannext = nextpoll(cleanup,  2400);
  456.          }
  457.  
  458.          if (nopassive)
  459.             busywork(next < cleannext ? next : cleannext);
  460.          else {
  461.             time_t spin;
  462.             returncode = passive(next < cleannext ? next : cleannext ,
  463.                                  debuglevel, logname , modem );
  464.  
  465.             if (returncode == 69 )  /* Error in UUCICO?              */
  466.             {                       /* Yes --> Allow time to fix it  */
  467.                spin = now + wait;   /* Figure next wait              */
  468.                wait *= 2 ;          /* Double wait for next time     */
  469.                busywork( spin > next ? next : spin );
  470.                                     /* But only wait till next poll  */
  471.             } /* if (returncode == 69 ) */
  472.             else {
  473.                wait = 10;
  474.  
  475.                if ((returncode == 0) && (autowait != -1) &&
  476.                    (now > autonext) && (now < next))
  477.                {
  478.                   returncode = active("any",debuglevel, logname);
  479.                   autonext = now + autowait;
  480.                } /* if */
  481.  
  482.             } /* else */
  483.  
  484.             if ( (now > exittime) && (now < next))
  485.                done = TRUE;
  486.             else if ( returncode == 100 )
  487.                done = TRUE;
  488.  
  489.          } /* else */
  490.  
  491.       } /* while */
  492.  
  493. /*--------------------------------------------------------------------*/
  494. /*                      Actively poll if needed                       */
  495. /*--------------------------------------------------------------------*/
  496.  
  497.       if ( ! done && (first >= 0) )
  498.       {
  499.          returncode = active(Rmtname,debuglevel,logname);
  500.  
  501.          if ( returncode == 100 )
  502.             done = TRUE;
  503.  
  504.       } /* if ( ! done && (first >= 0) ) */
  505.  
  506.    } /* while */
  507.  
  508. /*--------------------------------------------------------------------*/
  509. /*                          End of main loop                          */
  510. /*--------------------------------------------------------------------*/
  511.  
  512.    uuxqt( debuglevel );          /* One last call to UUXQT                 */
  513.  
  514. #ifndef FAMILYAPI
  515.    if (!cbrk)
  516.       setcbrk(0);                /* Restore original Cntrl-Break setting   */
  517. #endif
  518.  
  519.    printmsg(2,"UUPOLL exiting with return code %d", returncode );
  520.  
  521.    exit(returncode);
  522.  } /* main */
  523.  
  524. /*--------------------------------------------------------------------*/
  525. /*    L i f e  S p a n                                                */
  526. /*                                                                    */
  527. /*    Compute time to run program                                     */
  528. /*--------------------------------------------------------------------*/
  529.  
  530. static time_t LifeSpan( time_t duration, time_t stoptime )
  531. {
  532.    time_t exittime = LONG_MAX;
  533.    struct tm  *time_record;
  534.    time_t quit;
  535.  
  536. /*--------------------------------------------------------------------*/
  537. /*             Compute relative quitting time, if desired             */
  538. /*--------------------------------------------------------------------*/
  539.  
  540.    if (duration != -1)
  541.       exittime = hhmm2sec( duration ) + (now / 60L) * 60L;
  542.  
  543. /*--------------------------------------------------------------------*/
  544. /*    Compute absolute quitting time, if desired.  Must terminate     */
  545. /*    before midnight unless relative time was given as well, in      */
  546. /*    which case it must terminate before relative time would         */
  547. /*    expire.                                                         */
  548. /*--------------------------------------------------------------------*/
  549.  
  550.    if (stoptime != -1)
  551.    {
  552.  
  553. /*--------------------------------------------------------------------*/
  554. /*               Compute the absolute termination time                */
  555. /*--------------------------------------------------------------------*/
  556.  
  557.       time_record = localtime(&now);
  558.       time_record->tm_sec = 0;
  559.       time_record->tm_min = (int) (stoptime % 100);
  560.       time_record->tm_hour= (int) (stoptime / 100);
  561.       quit = mktime(time_record);
  562.  
  563.       if ( quit < now )             /* Number should be in future    */
  564.          quit += hhmm2sec( 2400 );
  565.  
  566. /*--------------------------------------------------------------------*/
  567. /*              Compute default relative time, if needed              */
  568. /*--------------------------------------------------------------------*/
  569.  
  570.       if ( duration == -1 )
  571.       {
  572.          time_record->tm_min = 0;
  573.          time_record->tm_hour= 24;
  574.          exittime = mktime(time_record);
  575.       }
  576.  
  577. /*--------------------------------------------------------------------*/
  578. /*                  Determine if we should use time                   */
  579. /*--------------------------------------------------------------------*/
  580.  
  581.       if ( exittime < quit )
  582.       {
  583.  
  584.          printf("*** Exiting ***\tProgram was to execute until %s",
  585.                      ctime(&quit));
  586.  
  587.          printf("\t\twhich would exceed retirement at %s",
  588.                      ctime(&exittime));
  589.          exit(10);
  590.  
  591.       } /* if ( exittime < now ) */
  592.       else
  593.          exittime = quit;
  594.  
  595.    } /* else if (stoptime != -1) */
  596.  
  597.    if (exittime != LONG_MAX)
  598.       printf("Will terminate upon completion of first event after %s",
  599.               ctime(&exittime));
  600.  
  601.    return exittime;
  602.  
  603. } /* LifeSpan */
  604.  
  605. /*--------------------------------------------------------------------*/
  606. /*    a c t i v e                                                     */
  607. /*                                                                    */
  608. /*    Perform an active (outgoing) poll of other hosts                */
  609. /*--------------------------------------------------------------------*/
  610.  
  611.  static active(char *Rmtname, int debuglevel, const char *logname)
  612.  {
  613.    int result;
  614.  
  615.    if (Rmtname == NULL)             /* Default?                         */
  616.    {                                /* Yes --> do -s all and -s any     */
  617.       if (active("all",debuglevel, logname ) < 100)
  618.          return active("any",debuglevel, logname);
  619.       else
  620.          return 100;
  621.    }
  622.    else {
  623.       char buf[128];
  624.       sprintf(buf,"uucico -r 1 -s %s -x %d",Rmtname,debuglevel);
  625.  
  626.       if ( logname != NULL )
  627.          strcat( strcat( buf, " -l ") , logname );
  628.       result = execute(buf);
  629.       if ( result == 0 )
  630.          uuxqt( debuglevel );
  631.  
  632.  
  633.       printmsg(2,"active: Return code = %d", result );
  634.  
  635.       return result;
  636.    }
  637.  } /* active */
  638.  
  639. /*--------------------------------------------------------------------*/
  640. /*    b u s y w o r k                                                 */
  641. /*                                                                    */
  642. /*    Waits for next time to poll without answering the telephone.    */
  643. /*    Maybe we should at least beep on the hour?  :-)                 */
  644. /*--------------------------------------------------------------------*/
  645.  
  646. static void busywork( time_t next)
  647. {
  648.    time_t naptime;
  649.    time_t hours, minutes, seconds;
  650.  
  651.    naptime = next - now;
  652.  
  653.    hours   = (naptime / 3600) % 24;    /* Get pretty time to display... */
  654.    minutes = (naptime / 60) % 60;
  655.    seconds = naptime % 60;
  656.  
  657.    printf("Going to sleep for %02ld:%02ld:%02ld, next poll is %s",
  658.              hours, minutes, seconds, ctime(&next) );
  659.    ssleep( naptime );
  660.  
  661.    time( & now );
  662. }
  663.  
  664.  
  665. /*--------------------------------------------------------------------*/
  666. /*    e x e c u t e                                                   */
  667. /*                                                                    */
  668. /*    Executes a command via a spawn() system call.  This avoids      */
  669. /*    the storage overhead of COMMAND.COM and returns the actual      */
  670. /*    return code from the command executed.                          */
  671. /*                                                                    */
  672. /*    Note that this does not allow quoted command arguments, which   */
  673. /*    not a problem for the intended argv[0]s of UUCICO.              */
  674. /*--------------------------------------------------------------------*/
  675.  
  676.  static int execute( char *command )
  677.  {
  678.    char *argv[20];
  679.    int argc = 0;
  680.    int result;
  681. #ifdef DEBUG
  682.    FILE *stream = NULL;
  683. #endif
  684.  
  685.    printf("Executing command: %s\n",command);
  686. #ifdef DEBUG                  /* ahd */
  687.    stream = fopen("UUPOLL.LOG","a");
  688.    if (stream == NULL)
  689.    {
  690.       printerr("UUPOLL.LOG");
  691.       panic();
  692.    } /* if */
  693.    fprintf(stream, "%s: %s\n",arpadate(), command);
  694.    fclose(stream);
  695. #endif /* DEBUG */
  696.  
  697.    argv[argc] = strtok(command," \t");
  698.  
  699.    while ( argv[argc++] != NULL )
  700.       argv[argc] = strtok( NULL," \t");
  701.  
  702.    result = spawnvp(P_WAIT , argv[0] , argv );
  703.  
  704.    if ( result < 0 )
  705.    {
  706.       printerr( argv[0] );
  707.       printf("\a\nCommand \"%s\" failed completely.\n\a", argv[0]);
  708.       panic();
  709.    }
  710.  
  711.    time( & now );
  712.  
  713.    printmsg(2,"execute: %s return code = %d",
  714.             argv[0], result );
  715.    return result;
  716. }
  717.  
  718. /*--------------------------------------------------------------------*/
  719. /*    n e x t p o l l                                                 */
  720. /*                                                                    */
  721. /*    Returns next time to poll in seconds                            */
  722. /*                                                                    */
  723. /*    modified 14 October 1990 By Ed Keith.                           */
  724. /*    modified 4 November 1990 by Drew Derbyshire.                    */
  725. /*--------------------------------------------------------------------*/
  726.  
  727. static time_t nextpoll( hhmm first, hhmm interval )
  728. {
  729.    time_t sfirst;
  730.    time_t sinterval = hhmm2sec( interval );
  731.    time_t today;
  732.    time_t tomorrow;
  733.    struct tm  *time_record;   /* Ed K. 10/14/1990 */
  734.  
  735.    time_record = localtime(&now); /* Ed K. 10/14/1990 */
  736.    time_record->tm_sec = 0;   /* Ed K. 10/14/1990 */
  737.    time_record->tm_min = 0;   /* Ed K. 10/14/1990 */
  738.    time_record->tm_hour= 0;   /* Ed K. 10/14/1990 */
  739.    today = mktime(time_record);
  740.  
  741. /*--------------------------------------------------------------------*/
  742. /*    We could just add hhmm2sec(2400) (24 hours) except this         */
  743. /*    doesn't work during days when we do a daylight savings          */
  744. /*    shift.  So we let the run time library compute midnight.        */
  745. /*--------------------------------------------------------------------*/
  746.  
  747.    time_record->tm_hour = 23;   /* Advance to midnight     */
  748.    time_record->tm_min  = 59;
  749.    tomorrow = mktime(time_record) + 60;   /* Add a minute to 23:59   */
  750.  
  751.    sfirst = today + hhmm2sec(first);
  752.  
  753.    while (sfirst < now)
  754.       sfirst += sinterval;
  755.  
  756. /*--------------------------------------------------------------------*/
  757. /*    Since we restart the polling of each day anew, reset the        */
  758. /*    next poll time based if it is after midnight.  Note the         */
  759. /*    funny double compare, which handles the stricter of the two     */
  760. /*    tests for "tomorrow".                                           */
  761. /*--------------------------------------------------------------------*/
  762.  
  763.    if ((sfirst > tomorrow) || (sfirst > (today + hhmm2sec(2400))))
  764.       sfirst = tomorrow + hhmm2sec(first);
  765.  
  766.    return sfirst;
  767.  
  768. } /* nextpoll */
  769.  
  770.  
  771. /*--------------------------------------------------------------------*/
  772. /*    f i r s t p o l l                                               */
  773. /*                                                                    */
  774. /*    Determine first time to poll if not specified                   */
  775. /*--------------------------------------------------------------------*/
  776.  
  777. static hhmm firstpoll(hhmm interval)
  778. {
  779.    struct tm  *time_record;
  780.    time_t sfirst;
  781.    hhmm first;
  782.  
  783.    time_record = localtime(&now);
  784.    sfirst = ((time_t) time_record->tm_hour * 3600L +
  785.              (time_t) time_record->tm_min * 60L);
  786.    sfirst  = sfirst % hhmm2sec(interval);
  787.    first = (hhmm) ((sfirst / 3600L) * 100L + (sfirst % 3600L) / 60L);
  788.  
  789.    printf("First polling time computed to be %-2.2d:%-2.2d\n",
  790.          first / 100, first % 100);
  791.  
  792.    return first;
  793.  
  794. } /* firstpoll */
  795.  
  796. /*--------------------------------------------------------------------*/
  797. /*    n o t a n u m b e r                                             */
  798. /*                                                                    */
  799. /*    Examines string, returns true if non-numeric                    */
  800. /*--------------------------------------------------------------------*/
  801.  
  802.  static boolean notanumber( char *start)
  803.  {
  804.    char *number = start;
  805.    while (*number != '\0')
  806.    {
  807.       if (!isdigit(*number))
  808.       {
  809.          printf("Parameter must be numeric, was %s\n",start);
  810.          return TRUE;
  811.       }
  812.       number++;
  813.    }
  814.    return FALSE;
  815.  } /* notanumber */
  816.  
  817.  
  818. /*--------------------------------------------------------------------*/
  819. /*    p a s s i v e                                                   */
  820. /*                                                                    */
  821. /*    Invoke UUCICO in passive mode until next active poll (if any).  */
  822. /*--------------------------------------------------------------------*/
  823.  
  824.  static int passive( time_t next,
  825.                      int debuglevel,
  826.                      const char *logname,
  827.                      const char *modem )
  828.  {
  829.    char buf[128];             /* Buffer for execute() commands          */
  830.    time_t seconds = (next - now + 59);
  831.    time_t minutes;
  832.    int result;
  833.  
  834.    if ( seconds > INT_MAX)
  835.       seconds = (INT_MAX / 3600) * 3600;
  836.  
  837.    minutes = seconds / 60;
  838.  
  839.    sprintf(buf,"uucico -r 0 -x %d -d %02ld%02ld",
  840.                debuglevel,
  841.                minutes / 60, minutes % 60);
  842.  
  843.    if ( logname != NULL )
  844.       strcat( strcat( buf, " -l ") , logname );
  845.  
  846.    if ( modem != NULL )
  847.       strcat( strcat( buf, " -m ") , modem );
  848.  
  849.    result = execute(buf);
  850.    if ( result == 0 )
  851.       uuxqt( debuglevel );
  852.  
  853.    printmsg(2,"passive: Return code = %d", result );
  854.    return result;
  855.  
  856.  } /* passive */
  857.  
  858. /*--------------------------------------------------------------------*/
  859. /*    u u x q t                                                       */
  860. /*                                                                    */
  861. /*    Execute the UUXQT program to run files received by UUCICO       */
  862. /*--------------------------------------------------------------------*/
  863.  
  864.  static void uuxqt( int debuglevel)
  865.  {
  866.    int result;
  867.    char buf[128];             /* Buffer for execute() commands          */
  868.  
  869.    sprintf(buf,"uuxqt -x %d", debuglevel);
  870.    result = execute(buf);
  871.  
  872.    if ( result != 0 )
  873.    {
  874.       printf("UUXQT failed with a return code of %d\n",result);
  875.       panic();
  876.    } /* if ( result != 0 ) */
  877.  
  878.  } /* uuxqt */
  879.  
  880. /*--------------------------------------------------------------------*/
  881. /*    C a t c h e r                                                   */
  882. /*                                                                    */
  883. /*    Catch Ctrl-Break                                                */
  884. /*--------------------------------------------------------------------*/
  885.  
  886.  void Catcher( void )
  887.  {
  888.  
  889.     safeout("uupoll: Program aborted by user\r\n");
  890.  
  891.     _exit(100);
  892.  } /* Catcher */
  893.  
  894. /*--------------------------------------------------------------------*/
  895. /*    u s a g e                                                       */
  896. /*                                                                    */
  897. /*    Report correct usage of the program and then exit.              */
  898. /*--------------------------------------------------------------------*/
  899.  
  900.  static void usage( char *name )
  901.  {
  902.    printf("Usage:\t%s"
  903.           "\t[-a hhmm] [-d hhmm | -e hhmm] [-f hhmm] [-i hhmm]\n"
  904.           "\t\t[-l logname] [-c hhmm] [-C command]\n"
  905.           "\t\t[-r 0 | 1] [-s system] [-x n]\n",name);
  906.    exit(4);
  907.  }
  908.  
  909. #ifndef FAMILYAPI
  910. #ifndef __TURBOC__
  911. /*--------------------------------------------------------------------*/
  912. /*    s e t c b r k                                                   */
  913. /*                                                                    */
  914. /*    Enable Cntrl-Break                                              */
  915. /*                                                                    */
  916. /*    Written by Dave Watt                                            */
  917. /*--------------------------------------------------------------------*/
  918.  
  919. static int setcbrk(char state)
  920. {
  921.    union REGS inregs, outregs;
  922.  
  923.    inregs.x.ax = 0x3302;
  924.    inregs.h.dl = state;
  925.    intdos(&inregs, &outregs);
  926.  
  927.    return outregs.h.dl;
  928. }
  929. #endif
  930. #endif
  931.